package com.mr.security.web.commons.mobile;

import lombok.Data;
import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.authentication.InternalAuthenticationServiceException;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;

/**
 * Class: SmsCodeAuthenticationProvider
 * User (作者):MRui
 * TODO (描述)：手机登陆验证Provider
 * Date 2019-01-26 21:38
 */
@Data
public class SmsCodeAuthenticationProvider implements AuthenticationProvider {


    private UserDetailsService userDetailsService;
    /**
    * User (作者): MRui
    * TODO (描述)：身份认证的逻辑
    * Data：2019-01-26 21:39
    */
    @Override
    public Authentication authenticate(Authentication authentication) throws AuthenticationException {

        SmsCodeAuthenticationToken authenticationToken = (SmsCodeAuthenticationToken)authentication;
        //读出传入的token信息（mobile）
        UserDetails user = userDetailsService.loadUserByUsername((String) authenticationToken.getPrincipal());
        if (user == null){
            throw new InternalAuthenticationServiceException("无法获取用户信息");
        }
        //重新构造token选用两个构造函数传入用户信息和权限
        SmsCodeAuthenticationToken authenticationTokenResult = new SmsCodeAuthenticationToken(user,user.getAuthorities());
        //将未认证的detail（过滤器已经set）set到已认证的结果token中去
        authenticationTokenResult.setDetails(authenticationToken.getDetails());
        //返回
        return authenticationTokenResult;
    }

    /**
    * User (作者): MRui
    * TODO (描述)：AuthenticationManager会根据此方法选择provider来处理token
    * Data：2019-01-26 21:39
    */
    @Override
    public boolean supports(Class<?> authentication) {
        return SmsCodeAuthenticationToken.class.isAssignableFrom(authentication);
    }
}
